<?php
require_once (ADMIN_CONTROLLER_FILE);

// DB connection
class UserController {
    
    private $DB;
    private $UID;
    
    private $ErrorMSG;
    
    // C'tor 
    // get DB Connection
    public function __construct($db_conection)    {
        $this->DB = $db_conection;
    }
    
    /** STATIC PART **/
    public static function isLoggedIn()  {
        if( isset($_SESSION['valid']) && $_SESSION['valid'] )  {
            //$this->UID = self::DecodeUID($_SESSION['userid']);
            return true;
        }
        else  {
            return false;
        }
    }

    // For GAME PHP
    public static function isPlaying()  {
        if( isset($_SESSION['playing']) && $_SESSION['playing'] )  {
            return true;
        }
        else  {
            return false;
        }
    }
    public static function SetPlaying($var)  {
        $_SESSION['playing'] = $var;
        self::SetWatingForGame(0);  //(start OR stop) playing -> waiting=false
        if ( ! $var ) { // if game ended - end the game
            self::SetGameID(0);
        }
    }  
    /* Wating For Game */
    public static function isWatingForGame()  {
        if( isset($_SESSION['waiting']))
            return $_SESSION['waiting'];
        else
            return 0;
    }
    public static function SetWatingForGame($val)  {
        $_SESSION['waiting'] = $val;
    }   
    public static function getGameID()  {
        if ( isset ($_SESSION['game_id']) && $_SESSION['game_id'] ) {
            return $_SESSION['game_id'];
        }
        else {
            return 0;
        }
    }
    public static function SetGameID($val)  {
        $_SESSION['game_id'] = $val;
    }
    /* end Wating For Game */
    
    //
    
    public static function executeLogout()  {
        $_SESSION = array(); //destroy all of the session variables
        session_destroy();
    }
    
    public static function EncodeUID($id) {
        return base64_encode($id);
    }
    
    public static function DecodeUID($id) {
        return base64_decode($id);
    }
    
    /** STATIC GETTERS **/
    public static function getUserID()  {
        if( isset($_SESSION['userid']))
            return self::DecodeUID($_SESSION['userid']);
        else
            return "";
    }
    public static function getUserNickname()  {
        if( isset($_SESSION['nick_name']))
            return $_SESSION['nick_name'];
        else
            return "";
    }
    public static function getUserAvatar()  {
        if( isset($_SESSION['avatar']))
            return $_SESSION['avatar'];
        else
            return "";
    }      
    public static function getUserPoints()  {
        if( isset($_SESSION['points']))
            return $_SESSION['points'];
        else
            return "";
    }
    public static function setUserPoints($val)  {
        $_SESSION['points'] = $val;
    }    
    public static function getUserWinCount()  {
        if( isset($_SESSION['win_count']))
            return $_SESSION['win_count'];
        else
            return "";
    }
    public static function setUserWinCount($val)  {
        $_SESSION['win_count'] = $val;
    }     
    public static function getUserLooseCount()  {
        if( isset($_SESSION['loose_count']))
            return $_SESSION['loose_count'];
        else
            return "";
    }
    public static function setUserLooseCount($val)  {
        $_SESSION['loose_count'] = $val;
    }         
    
    
    
    /** end of STATIC PART **/
    
    
    //creates a 3 character sequence (HEX)
    function createSalt()  {
        $string = md5(uniqid(rand(), true));
        return substr($string, 0, 3);
    }
    
    // validate user after successful login
    // need to SET UID Before !!
    function validateUser()  {   
        session_regenerate_id (); //this is a security measure

        $query = "SELECT *
               FROM users       
               WHERE id = ?
               LIMIT 1";       
        
        if ($this->DB->executeBindedQuery($query,"i",$this->UID)) {
            $result = $this->DB->getResult();
            if( ($result != null) && ($result->num_rows == 1) ) {
                $row = $result->fetch_assoc();
                $_SESSION['valid'] = 1;
                $_SESSION['userid'] = self::EncodeUID($this->UID);
                $_SESSION['nick_name'] = $row['nick']; 
                $_SESSION['avatar'] = $row['avatar']; 
                $_SESSION['points'] = $row['points']; 
                $_SESSION['win_count'] = $row['win']; 
                $_SESSION['loose_count'] = $row['loose']; 
                $_SESSION['waiting'] = 0;           // for waiting room (waiting_state)
                $_SESSION["waiting_started"] = 0;   // for waiting room (waiting_state)
                
                self::SetGameID($row['game_id']);
                if ($row['game_id'] !=0 ) { 
                    UserController::SetPlaying(1);
                }
                
                return true;
            }
            else {
                $this->ErrorMSG = "User not found";
                return false;
            }
        }
        else {
            $this->ErrorMSG = $this->DB->getErrorMSG();
            return false;
        }

    }     
    
    // check if user name already exist
    public function isUserExist($uname) {
        $this->ErrorMSG = "";
        
        $query = "SELECT *
                FROM users       
                WHERE username = ?
                LIMIT 1";
        
        if ($this->DB->executeBindedQuery($query,"s",$uname)) {
            $result = $this->DB->getResult();
            if( ($result != null) && ($result->num_rows == 1) ) {
                return true;
            }
            else {
                $this->ErrorMSG = "";
                return false;
            }
        }
        else {
            if(DEBUG) {
                $this->ErrorMSG = $this->DB->getErrorMSG();
            }
            else {
                $this->ErrorMSG = "An error occurred, please try again later";
            }           
            return false;
        }
    }
    
    
    // check if Nick name already exist
    public function isNickNameExist($nick) {
        $this->ErrorMSG = "";
        
        $query = "SELECT *
                FROM users       
                WHERE nick = ?
                LIMIT 1";
        
        if ($this->DB->executeBindedQuery($query,"s",$nick)) {
            $result = $this->DB->getResult();
            if( ($result != null) && ($result->num_rows == 1) ) {
                return true;
            }
            else {
                $this->ErrorMSG = "";
                return false;
            }
        }
        else {
            if(DEBUG) {
                $this->ErrorMSG = $this->DB->getErrorMSG();
            }
            else {
                $this->ErrorMSG = "An error occurred, please try again later";
            }           
            return false;
        }
    }    
    
    
    
    //get error msg
    public function getErrorMSG() {
        return $this->ErrorMSG;
    }




    // Execute User LogIn
    // return true if user exist + validate the user with Sessions
    // return false with ErrorMSG otherwise (user not exist\pass error\DBError)
    public function executeLogin($uname , $pass)  {
        
        // first check for admin login
        if ( $uname == AdminController::getAdminUser() && 
                $pass == AdminController::getAdminPass() ) {
            // admin Logged In!!
            AdminController::executeAdminLogin();
            // validation passed 
            return true;
        }
        
        //else:
        AdminController::executeAdminLogout();
        
        // Now look for the user..
        $query = "SELECT *
                FROM users       
                WHERE username = ?
                LIMIT 1";
        
        if ($this->DB->executeBindedQuery($query,"s",$uname)) {
            $result = $this->DB->getResult();
            
            if( ($result != null) && ($result->num_rows == 1) ) {
                $row = $result->fetch_assoc();
                
                $hash = hash('sha256', $row['salt'] . hash('sha256', $pass) );
                
                if($hash != $row['pass']) //incorrect password
                {   
                    $this->ErrorMSG = "Incorrect Username/Password Combination";
                    return false;
                }
                else
                {
                    // Login Passed !
                    $this->UID  = $row['id'];
                    if ( ! $this->validateUser() ) { //sets the session data for this user
                        if( ! DEBUG ) {
                            $this->ErrorMSG = "An error occurred, please try again later";
                        }
                        return false;    
                    }
                    // validation passed (with generate session for nick name)!
                    return true;
                }                
            }
            else {
                $this->ErrorMSG = "Incorrect Username/Password Combination";
                return false;
            }
        }
        else {
            if(DEBUG) {
                $this->ErrorMSG = $this->DB->getErrorMSG();
            }
            else {
                $this->ErrorMSG = "An error occurred, please try again later";
            }
            return false;            
        }
    }

    // Register New User
    // return true if successful 
    // return false with Empty ErrorMSG if user already exist
    // return false with ErrorMSG on DB error
    public function executeRegister($uname , $pass , $mail , $nick , $avatar)    {
        
        if ( $this->isUserExist($uname) ) {
            if ($this->ErrorMSG == "") { // user already exist
                return false;   // with empty ErrorMSG
            }
            else { // DB error
                if (DEBUG)
                    $this->ErrorMSG = $this->DB->getErrorMSG();
                else
                   $this->ErrorMSG = "An error occurred, please try again later";
                return false;   //with ErrorMSG             
            }
        }
        else {
            if ( strlen($this->ErrorMSG)>0 ) {  //isUserExist returns Error
                return false;
            }
        }
        
        $salt = $this->createSalt();
        $hash = hash('sha256', $pass);
        $hash = hash('sha256', $salt . $hash);

        $query = "INSERT INTO users ( 
            username,
            email,
            pass,
            salt,
            nick,
            avatar,
            points,
            win,
            loose, game_id)
            VALUES ( ? , ? , '$hash' , '$salt' , ? , ? , 0 , 0 , 0 , 0);";

        if ($this->DB->executeBindedQuery($query,"sssi",$uname,$mail,$nick,$avatar)) {
            // REG PASSED!
            $this->UID = $this->DB->getLastInsertID();  //save user ID
            if ( ! $this->validateUser() ) { //sets the session data for this user
                if( ! DEBUG ) {
                    $this->ErrorMSG = "An error occurred, please try again later";
                }
                return false;    
            }         
            // REG PASSED with Validation!
            return true;
        }
        else {
            if (DEBUG)
                $this->ErrorMSG = $this->DB->getErrorMSG();
            else
                $this->ErrorMSG = "An error occurred, please try again later";
            return false;
        }
    }    
    
    
    // Get UID
    public function getUID() {
        return $this->UID;
    }
    

}